package com.swapper.hls.tag;

/**
 * #EXTM3U {@link M3UTag}
 * #EXT-X-VERSION:<n> {@link VersionTag}
 * #EXTINF:<duration>,[<title>] {@link InfTag}
 * #EXT-X-BYTERANGE:<n>[@<o>] {@link ByteRangeTag}
 * #EXT-X-DISCONTINUITY {@link DiscontinuityTag}
 * #EXT-X-KEY:<attribute-list> {@link KeyTag}
 * - METHOD
 * - URI
 * - IV
 * - KEYFORMAT
 * - KEYFORMATVERSIONS
 * #EXT-X-MAP:<attribute-list> {@link MapTag}
 * - URI
 * - BYTERANGE
 * #EXT-X-PROGRAM-DATE-TIME:<date-time-msec> {@link ProgramDateTimeTag}
 * #EXT-X-DATERANGE:<attribute-list> {@link DateRangeTag}
 * - ID
 * - CLASS
 * - START-DATE
 * - END-DATE
 * - DURATION
 * - PLANNED-DURATION
 * - X-<client-attribute>
 * - SCTE35-CMD
 * - SCTE35-OUT
 * - SCTE35-IN
 * - END-ON-NEXT
 * #EXT-X-TARGETDURATION:<s> {@link TargetDurationTag}
 * #EXT-X-MEDIA-SEQUENCE:<number> {@link MediaSequenceTag}
 * #EXT-X-DISCONTINUITY-SEQUENCE:<number> {@link DiscontinuitySequenceTag}
 * #EXT-X-ENDLIST {@link EndListTag}
 * #EXT-X-PLAYLIST-TYPE:<type-enum> {@link PlayListTypeTag}
 * #EXT-X-I-FRAMES-ONLY {@link IFramesOnlyTag}
 * #EXT-X-MEDIA:<attribute-list> {@link MediaTag}
 * - TYPE
 * - URI
 * - GROUP-ID
 * - LANGUAGE
 * - ASSOC-LANGUAGE
 * - NAME
 * - DEFAULT
 * - AUTOSELECT
 * - FORCED
 * - INSTREAM-ID
 * - CHARACTERISTICS
 * - CHANNELS
 * #EXT-X-STREAM-INF:<attribute-list> {@link StreamInfTag}
 * <URI>
 * - BANDWIDTH
 * - AVERAGE-BANDWIDTH
 * - CODECS
 * - RESOLUTION
 * - FRAME-RATE
 * - HDCP-LEVEL
 * - AUDIO
 * - VIDEO
 * - SUBTITLES
 * - CLOSED-CAPTIONS
 * #EXT-X-I-FRAME-STREAM-INF:<attribute-list> {@link IFrameStreamInfTag}
 * - URI
 * #EXT-X-SESSION-DATA:<attribute-list> {@link SessionDataTag}
 * - DATA-ID
 * - VALUE
 * - URI
 * - LANGUAGE
 * #EXT-X-SESSION-KEY:<attribute-list> {@link SessionKeyTag}
 * - METHOD
 * - URI
 * - IV
 * - KEYFORMAT
 * - KEYFORMATVERSIONS
 * #EXT-X-INDEPENDENT-SEGMENTS {@link IndependentSegmentsTag}
 * #EXT-X-START:<attribute-list> {@link StartTag}
 * - TIME-OFFSET
 * - PRECISE
 */
public abstract class AbstractTag {
  protected final String mName;

  protected AbstractTag(String name) {
    if (name == null) {
      throw new NullPointerException("The HLS tag name is null.");
    }
    mName = name;
  }

  public final String name() {
    return mName;
  }

  @Override
  public String toString() {
    return String.format("%s\n", mName);
  }

  public static abstract class AbstractAttribute<T> {
    protected final String mName;
    protected final T mValue;

    protected AbstractAttribute(String name, T value) {
      if (name == null) {
        throw new NullPointerException("The HLS attribute name is null.");
      }
      mName = name;
      mValue = verify(value);
    }

    protected abstract T verify(T value);

    public final String name() {
      return mName;
    }

    public final T value() {
      return mValue;
    }

    @Override
    public String toString() {
      return String.format("%s=%s", mName, mValue);
    }
  }
}
